/*********************************************************************\
*
*                  (c) lkc
*                  All Rights Reserved. lkc Confidential
*
\*********************************************************************/
/*********************************************************************\
*   Title                      :
*
*   Module Description         :
*
*   Author                     : lkc
*
*   Created                    : 2018-7-3
*
\*********************************************************************/


#include "ProtocolPC.h"
#ifdef PC_IS_ALIVE
#include "CamGainControl.h"
#include "ImageDetect.h"
#include "CamControl.h"
#include "DisplayControl.h"
#include "UtilityTH.h"
//#include "ProtocolMCU.h"
#include "VedioRecord.h"
#include "FocusControl.h"

ProtocolPC ProtocolPC::m_Instance;

void ProtocolPC::ExtractData(const unsigned char *data, int nLength)
{
    m_bufferTempMtx.lock();
    m_bufferTemp.insert(m_bufferTemp.end(),data,data+nLength);
    while( m_bufferTemp.size() >= FRAME_LENGTH_RECEIVE)
    {
        auto iter = m_bufferTemp.begin();
        if (*iter != HEAD1)
        {
            //如果数据开始不是头，则删除数据
            m_bufferTemp.erase(iter);
            continue;
        }
        if(*(iter+1) != HEAD2_EVENT)
        {
            m_bufferTemp.erase(iter);
            continue;
        }
        if(*(iter+FRAME_LENGTH_RECEIVE-1) != END)
        {
            m_bufferTemp.erase(iter,iter+2);//删除头上两个数据
            continue;
        }

        unsigned char sum = CheckSum(iter+2,3);
        if(*(iter+FRAME_LENGTH_RECEIVE-2) != sum)
        {
            m_bufferTemp.erase(iter,iter+2);//删除头上两个数据
            continue;
        }
        //到此，找到一帧完整的数据
        EventReceiveFrameParse();
        m_bufferTemp.erase(iter,iter+FRAME_LENGTH_RECEIVE);
    }
     m_bufferTempMtx.unlock();
}

void ProtocolPC::EventReceiveFrameParse()
{
    m_funcCodeReceive = m_bufferTemp[2];
    m_commandReceive = m_bufferTemp[3];
    m_dataReceive = m_bufferTemp[4];
    switch (m_funcCodeReceive)
    {
    case 0xC0:
        SelfCheckParse();
        break;
    case 0xC1:
        GainParse();
        break;
    case 0xC2:
        FoucsParse();
        break;
    case 0xC3:
        ContrastParse();
        break;
    case 0xC4:
        OutModeParse();
        break;
    case 0xC5:
        WorkModeParse();
        break;
    case 0xC6:
        RecordParse();
        break;
    case 0xC7:
        CrossParse();
        break;
    default:
        break;
    }

}

void ProtocolPC::SelfCheckParse()
{
    if(m_commandReceive == 0x01)//启动相机自检
    {
        focusCtl.MotoSelfCheck();
        //ProtocolMCU::GetInstance().MotoSelfCheck();
    }
}

void ProtocolPC::GainParse()
{
    switch(m_commandReceive)
    {
    case 0x01://增加增益
        CamGainControl::GetInstance().IncGain();
        break;
    case 0x02://减小增益
        CamGainControl::GetInstance().DecGain();
        break;
    case 0x03://设置增益绝对值
        CamGainControl::GetInstance().SetGain(m_dataReceive);
        break;
    case 0x04://增益自动调节
        CamGainControl::GetInstance().SetGainAutoMode(true);
        break;
    default:
        return;
    }
}

void ProtocolPC::FoucsParse()
{
    switch(m_commandReceive)
    {
    case 0x01://增加焦距
        focusCtl.IncFocus();
        //ProtocolMCU::GetInstance().IncFocus();
        break;
    case 0x02://减小焦距
        focusCtl.DecFocus();
        //ProtocolMCU::GetInstance().DecFocus();
        break;
    case 0x03://设置焦距绝对值
        focusCtl.SetFocus(m_dataReceive);
        //ProtocolMCU::GetInstance().SetFocus(m_dataReceive);
        break;
    case 0x04://设置焦距自动调节

        break;
    default:
        return;
    }
}

void ProtocolPC::ContrastParse()
{
    switch(m_commandReceive)
    {
    case 0x01://增加对比度
        IncContrast();
        break;
    case 0x02://减小对比度
        DecContrast();
        break;
    case 0x03://设置对比度绝对值
        SetContrast(m_dataReceive);
        break;
    case 0x04://设置对比度自动调节

        break;
    default:
        return;
    }
}

void ProtocolPC::OutModeParse()
{
    switch(m_commandReceive)
    {
    case 0x01://原图输出模式
        SetOutMode(OutMode::ORIGINAL);
        break;
    case 0x02://增强输出模式
        SetOutMode(OutMode::ENHANCE);
        break;
    case 0x03://信息叠加模式
        SetOutMode(OutMode::SUPERPOSITION);
        break;
    default:
        return;
    }
}

void ProtocolPC::WorkModeParse()
{
    switch(m_commandReceive)
    {
    case 0x01://工作模式
        CamControl::GetInstance().SetWorkMode(true);        
        break;
    case 0x02://待机模式，切断CCD与调焦系统
        CamControl::GetInstance().SetWorkMode(false);
        break;
    default:
        return;
    }
}

void ProtocolPC::RecordParse()
{
    switch(m_commandReceive)
    {
    case 0x01://开始录制
        StartVedioRecord();
        break;
    case 0x02://结束录制
        StopVedioRecord();
        break;
    default:
        return;
    }
}

void ProtocolPC::CrossParse()
{
    switch(m_commandReceive)
    {
    case 0x01://加载十字线
        SetCrossMode(true);
        break;
    case 0x02://消隐十字线
        SetCrossMode(false);
        break;
    default:
        return;
    }
}

void ProtocolPC::BuildFrame()
{
    m_frameToSend[0] = HEAD1;
    m_frameToSend[1] = HEAD2_EVENT;
    m_frameToSend[2] = m_funcCodeSend;
    m_frameToSend[3] = m_commandSend;
    m_frameToSend[4] = m_dataSend;
    m_frameToSend[5] = m_resultSend;
    m_frameToSend[6] = CheckSum(&m_frameToSend[2],4);
    m_frameToSend[7] = END;
}

int ProtocolPC::SendFrame()
{
    BuildFrame();
    int ret = Send(m_frameToSend,FRAME_LENGTH_EVENT_SEND);
//    int ret = m_port.Send(m_frameToSend,FRAME_LENGTH_EVENT_SEND);
    if (ret < 0)
    {
        printf("ProtocolPC write data error!\n");
    }
    return ret;
}

int ProtocolPC::CycleSendOnce()
{
    int frameLenghtMax = 100;
    unsigned char frameToSendCycle[frameLenghtMax];
    memset(frameToSendCycle,0,frameLenghtMax);
    frameToSendCycle[0] = HEAD1;
    frameToSendCycle[1] = HEAD2_CYCLE;
    frameToSendCycle[2] = NORMAL_CYCLE;   //数据有效性 0x00 正常状态 0x01 异常状态
    frameToSendCycle[3] = focusCtl.GetSelfCheckState()?0x00:0x01;   //自检状态
    //frameToSendCycle[3] = ProtocolMCU::GetInstance().GetSelfCheckState()?0x00:0x01;   //自检状态
    frameToSendCycle[4] = CamGainControl::GetInstance().GetGain();
    frameToSendCycle[5] = focusCtl.GetFocus();
//    frameToSendCycle[5] = ProtocolMCU::GetInstance().GetFocus();
    frameToSendCycle[6] = GetContrast();
    OutMode mode = GetOutMode();
    unsigned char modeData;
    if(mode == OutMode::ORIGINAL)
    {
        modeData = 0x00;
    }
    else if(mode == OutMode::ENHANCE)
    {
        modeData = 0x01;
    }
    else
    {
        modeData = 0x02;
    }
    frameToSendCycle[7] = modeData;
    frameToSendCycle[8] = CamControl::GetInstance().GetWorkMode()?0x01:0x00;   //运行模式 GetWorkMode
    frameToSendCycle[9] = CamControl::GetInstance().GetVideoRecordSate()?0x00:0x01;
    frameToSendCycle[10] = GetCrossMode()?0x00:0x01;

    std::vector <cv::Point2f> points = ImageDetect::GetInstance().GetObjectPoints();
    frameToSendCycle[11] = points.size();
    int i = 12;
    for(unsigned int j = 0; j < points.size(); j++)
    {
        int xCode = static_cast<int>(points[j].x*10);
        int yCode = static_cast<int>(points[j].y*10);
        //x坐标，浮点数保留一位小数
       frameToSendCycle[i++] = xCode&0xFF;
       frameToSendCycle[i++] = (xCode>>8)&0xFF;
        //y坐标
       frameToSendCycle[i++] = yCode&0xFF;
       frameToSendCycle[i++] = (yCode>>8)&0xFF;
    }
    int count = i-2;
    frameToSendCycle[i++] = CheckSum(frameToSendCycle+2,count);       //校验和
    frameToSendCycle[i++] = 0xFB;       //帧尾
    int ret = Send(frameToSendCycle,i);
//    int ret = m_port.Send(frameToSendCycle,i);
    if (ret < 0)
    {
        printf("ProtocolPC write data error!\n");
    }
    return ret;
}

int ProtocolPC::GetOutModeInt()
{
    OutMode mode = GetOutMode();
    int outModeInt;
    if(mode == OutMode::ORIGINAL)
    {
        outModeInt = 0;
    }
    else if(mode == OutMode::ENHANCE)
    {
        outModeInt = 1;
    }
    else
    {
        outModeInt = 2;
    }
    return outModeInt;
}
#endif//#ifdef PC_IS_ALIVE

/********************************************************************\
 *
 * REVISION RECORDS
 *
\*********************************************************************/
/*********************************************************************/
/*
 *
 *
 *
\*********************************************************************/
/*------------------------------The End------------------------------*/
